// MIT License
// 开源地址：https://gitee.com/co1024/AbcMvc
// Copyright (c) 2021-2023 1024
// Abc.Mvc=Furion+EF+SqlSugar+Pear layui admin.

//https://www.cnblogs.com/hulizhong/p/10779687.html

using Microsoft.AspNetCore.Mvc.Controllers;

namespace Abc.Web.Core;

/// <summary>
///     Admin 权限过滤器
///     UseAuthorization();//授权
/// </summary>
public class AdminPermissionFilterAttribute : ActionFilterAttribute
{
    public AdminPermissionFilterAttribute()
    {
    }

    /// <summary>
    ///     构造函数
    /// </summary>
    /// <param name="permissionType">权限类型：默认HtAdmin</param>
    public AdminPermissionFilterAttribute(string permissionType = "HtAdmin")
    {
        PermissionType = permissionType;
    }

    /// <summary>
    ///     权限类型，默认HtAdmin
    /// </summary>
    public string PermissionType { get; set; } = "HtAdmin";

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //判断请求的控制器有没有加上NoPermissionRequiredAttribute或AllowAnonymousAttribute（不需要权限）
        var controllerAttributes = filterContext.Controller.GetCustomAttributes();
        if (controllerAttributes.Any(a =>
                a.GetType() == typeof(NoPermissionRequiredAttribute) ||
                a.GetType() == typeof(AllowAnonymousAttribute))) return;
        //判断请求的方法有没有加上NoPermissionRequiredAttribute或AllowAnonymousAttribute（不需要权限）
        var actionDescriptor = filterContext.ActionDescriptor as ControllerActionDescriptor;
        // 获取 Action 类型
        var methodType = actionDescriptor.MethodInfo;

        var controllerActionAttributes = methodType.GetCustomAttributes();
        if (controllerActionAttributes.Any(a =>
                a.GetType() == typeof(NoPermissionRequiredAttribute) ||
                a.GetType() == typeof(AllowAnonymousAttribute))) return;
        var filtercontextinfo = new FilterContextInfo(filterContext);
        if (filtercontextinfo.UserId <= 0)
            NoAuth(filterContext);
        else
        {
            var scopeFactory = App.GetService<IServiceScopeFactory>();
            using var scope = scopeFactory.CreateScope();
            var services = scope.ServiceProvider;

            //// 获取数据库上下文
            //var dbContext = Db.GetDbContext(services);
            // 获取仓储
            // var respository = Db.GetRepository<User>(services);
            var cacheService = App.GetService<ISysCacheService>(services);
            var isHasAuth = cacheService.HasAuthorize(PermissionType, filtercontextinfo.ControllerName,
                filtercontextinfo.ActionName, filtercontextinfo.UserId).GetAwaiter().GetResult();
            if (!isHasAuth) NoAuth(filterContext);
        }

        base.OnActionExecuting(filterContext);
    }

    private void NoAuth(ActionExecutingContext filterContext)
    {
        //没得权限
        filterContext.Result = new RedirectResult("/HtAdmin/Login/Index");

        //var content = new ContentResult();
        //content.Content = "没有权限";
        //content.StatusCode = 403;//403(Forbidden)：禁止。服务器拒绝接受请求。
        //filterContext.Result = content;
    }

    /// <summary>
    ///     不验证权限
    /// </summary>
    public class NoPermissionRequiredAttribute : ActionFilterAttribute
    {
    }
}